from typing import Annotated
from sqlalchemy.orm import Session
from fastapi import APIRouter, Depends, HTTPException , status, Path
from models import Todos
from database import sessionmaker
from pydantic import BaseModel , Field
from .auth import get_current_user


SessionLocal = sessionmaker


# 创建一个APIRouter实例
# prefix参数设置路由前缀为"/todos"
# tags参数用于在API文档中对路由进行分组标记
router = APIRouter(
    prefix="/todos",
    tags=["todos"],
)

# 定义获取数据库会话的依赖函数
def get_db():
    # 创建新的数据库会话
    db = SessionLocal()
    try:
        # 使用yield返回数据库会话
        yield db
    finally:
        # 确保在请求结束时关闭数据库会话
        db.close()

# 创建类型注解的数据库依赖项，用于FastAPI的依赖注入系统
db_dependency = Annotated[Session, Depends(get_db)]

# 创建用户依赖项，用于验证用户身份
# 使用Annotated标注类型为dict，依赖于get_current_user函数
# 这个依赖项会在每个需要用户认证的路由中使用
user_dependency = Annotated[dict, Depends(get_current_user)]



#创建pydantic model
class TodoRequest(BaseModel):
    title : str = Field(min_length=3)
    description : str = Field(min_length=3, max_length=100)
    priority : int = Field(gt=0, lt=5)
    complete : bool = False

@router.get("/")
async def read_all(user: user_dependency,db : db_dependency):
    if user is None:
        raise HTTPException(status_code=401, detail='Authentication Failed')
    return db.query(Todos).filter(Todos.owner_id == user.get('id')).all()

@router.get("/todo/{todo_id}" ,status_code=status.HTTP_200_OK)
async def read_todo(user: user_dependency ,db : db_dependency, todo_id : int = Path(gt=0)):
    if user is None:
        raise HTTPException(status_code=401, detail='Authentication Failed')
    todo_maodel = db.query(Todos).filter(Todos.id == todo_id).filter(Todos.owner_id == user.get("id")).first()
    if todo_maodel is not None:
        return todo_maodel
    raise HTTPException(status_code=404, detail='Todo not found')


@router.post("/todo/", status_code=status.HTTP_201_CREATED)
async def create_todo(user: user_dependency ,db : db_dependency, todo_request : TodoRequest):
    if user is None:
        raise HTTPException(status_code=401, detail='Authentication Failed')
    todo_model = Todos(**todo_request.model_dump() , owner_id = user.get('id'))
    db.add(todo_model)
    db.commit()
    return todo_model

@router.put("/todo/{todo_id}", status_code=status.HTTP_204_NO_CONTENT)
async def update_todo(user : user_dependency,db : db_dependency, 
                        todo_request : TodoRequest, 
                        todo_id : int = Path(gt=0)):
    if user is None:
        raise HTTPException(status_code=401, detail='Authentication Failed')
    todo_model = db.query(Todos).filter(Todos.id == todo_id).filter(Todos.owner_id == user.get('id')).first()
    if todo_model is None:
        raise HTTPException(status_code=404, detail='Todo not found')

    todo_model.title = todo_request.title
    todo_model.description = todo_request.description
    todo_model.priority = todo_request.priority
    todo_model.complete = todo_request.complete

    db.add(todo_model)
    db.commit()

@router.delete("/todo/{todo_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_todo(user: user_dependency,db : db_dependency, todo_id : int = Path(gt=0)):
    if user is None:
        raise HTTPException(status_code=401, detail='Authentication Failed')
    todo_model = db.query(Todos).filter(Todos.id == todo_id).filter(Todos.owner_id == user.get('id')).first()
    if todo_model is None:
        raise HTTPException(status_code=404, detail='Todo not found')

    db.query(Todos).filter(Todos.id == todo_id).delete() 
    db.commit()